Skip to content

Integration test: 2026-10-19 - #213

Draft
apiology wants to merge 613 commits into
masterfrom
2026-10-19
Draft

apiology wants to merge 613 commits into
masterfrom
2026-10-19

Conversation

@apiology

@apiology apiology commented Oct 19, 2026 •

Copy link
Copy Markdown
Owner

Claude: This PR was written by Claude Code on behalf of @apiology.

Problem:

Open PRs are tested only one at a time:

castwide/solargraph PRs, each tested only against its own base

A conflict between two of them would surface only after both merge.

Solution:

Merges every PR below into one branch so CI runs on the combination.

castwide/solargraph PRs included

  1. [regression fix] Make RuboCop block CI again, and auto-prune .rubocop_todo.yml castwide/solargraph#1260 — [regression fix] Make RuboCop block CI again, and auto-prune .rubocop_todo.yml
  2. [regression fix] Show undercover failures as a failed check without blocking merge castwide/solargraph#1047 — [regression fix] Show undercover failures as a failed check without blocking merge
  3. Spec performance fixes castwide/solargraph#1237 — Spec performance fixes
  4. [regression fix] Stop asserts crash on ivars in module_function methods castwide/solargraph#1429 — [regression fix] Stop asserts crash on ivars in module_function methods
  5. [regression fix] Resolve aliases of top-level methods castwide/solargraph#1430 — [regression fix] Resolve aliases of top-level methods
  6. [regression fix] Accept aliases of macro-defined methods with assertions on castwide/solargraph#1431 — [regression fix] Accept aliases of macro-defined methods with assertions on
  7. [regression fix] Stop closure asserts on methods in class << self and Struct.new blocks castwide/solargraph#1433 — [regression fix] Stop closure asserts on methods in class << self and Struct.new blocks
  8. [regression fix] Close @!attribute directive pins over their class, not the documented method castwide/solargraph#1432 — [regression fix] Close @!attribute directive pins over their class, not the documented method
  9. Fix a nil crash and missing nil checks across the parser, type checker and RBS handling castwide/solargraph#1245 — Fix a nil crash and missing nil checks across the parser, type checker and RBS handling
  10. [regression fix] Fix and re-enable strong-level typechecking in CI castwide/solargraph#1240 — [regression fix] Fix and re-enable strong-level typechecking in CI
  11. [regression fix] Stop rerunning a gem cache command that failed castwide/solargraph#1442 — [regression fix] Stop rerunning a gem cache command that failed
  12. [regression fix] Let conventions add source paths when mapping gems castwide/solargraph#1404 — [regression fix] Let conventions add source paths when mapping gems
  13. [regression fix] Create accessor pins for ActiveSupport macros in gem source castwide/solargraph#1446 — [regression fix] Create accessor pins for ActiveSupport macros in gem source
  14. [regression fix] Give gem caches the workspace's plugins castwide/solargraph#1407 — [regression fix] Give gem caches the workspace's plugins
  15. [regression fix] Let solargraph-rails spec failures fail CI again castwide/solargraph#1321 — [regression fix] Let solargraph-rails spec failures fail CI again
  16. [regression fix] Let overcommit failures fail CI again castwide/solargraph#1448 — [regression fix] Let overcommit failures fail CI again
  17. Read AST children with typesafe pattern-matching castwide/solargraph#1418 — Read AST children with typesafe pattern-matching

apiology/solargraph PRs included

  1. Cut CI duration from 20 minutes to 6 #44 — Cut CI duration from 20 minutes to 6

Notes

  • Rebuilt from castwide master da44db2 on 2026-10-20; every commit is one Merge <repo>#N merge commit.

apiology and others added 30 commits October 14, 2026 13:35
Replace positional children[N] reads in parser_gem/node_processors
with Ruby pattern matching against Parser::AST::Node#deconstruct
([type, *children]).

Every rewrite is a one-line `return ... unless node in [...]` guard
or a pattern inside an existing condition, so no shape the parser
produces raises where it did not before. An optional trailing child
(the value of an *asgn inside an mlhs, a default argument) is read
with `(rest in [value, *]) ? value : nil`.

RuboCop 1.80.0 Style/RedundantParentheses flags those parentheses,
and its autocorrect output is a SyntaxError ("unexpected '?'"), so
each such line carries an inline disable. RuboCop 1.92.0 no longer
flags it.

Solargraph defines no pins for pattern captures, so typecheck --level
strong reports each capture as an unresolved call; the Overcommit
Solargraph hook was skipped for that reason.

The sclass processor's scoped-casgn and arbitrary-expression paths
had no coverage; two api_map specs now exercise them.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
Replace positional children reads in the Struct and Data definition
node wrappers with Ruby pattern matching. The match? checks become
single patterns such as
`::Parser::AST::Node[:send, [:const, _, :Struct, *], :new, *]`.

keyword_init? no longer raises NoMethodError when the first hash
argument is empty (`Struct.new(:a, {})`); it returns false.

body_node had no caller and no coverage, and class_name's scoped
constant path (`Outer::Foo = Struct.new(:bar)`) was uncovered; specs
now exercise both for Struct and Data.

Solargraph defines no pins for pattern captures, so typecheck --level
strong reports each capture as an unresolved call; the Overcommit
Solargraph hook was skipped for that reason.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
Moved from castwide#1240 (3e8ae51), which must carry
only annotations, markers and typecheck config:

- repo.rb, require_paths.rb: Array#last is nilable; test the last
  line itself instead of the raw output before JSON.parse. repo.rb
  keeps its { metagems: [], groups: {} } fallback.
- shell.rb: extract Shell#profile_test_file to bring Shell#profile
  under the Metrics/AbcSize limit CI reports.

The rubocop_helpers.rb version.to_s change was already here.

New shell specs cover the missing-vernier, no-Ruby-files and CTRL-C
paths of Shell#profile and both profile_test_file fallbacks, so
undercover passes on the changed methods.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
Replace positional children reads in NodeChainer and
FlowSensitiveTyping with Ruby pattern matching.

NodeChainer#generate_links branched on n.type with an if/elsif
chain; it is now a case/in on the node's shape, in the same order
and with the same fallbacks. Two shapes the old reads accepted get
explicit clauses: an anonymous splat in an mlhs (s(:splat), no
value) still yields no links, and an empty begin...end (s(:kwbegin))
still yields none. The block_pass clauses moved to a private
block_pass_link so generate_links stays within the cyclomatic
complexity limit.

The send/csend "No idea what to do" raises and the receiverless
csend clause are unreachable from parsed source; specs now build
those nodes by hand so the touched method is fully covered.

Solargraph defines no pins for pattern captures and infers no type
for case/in, so typecheck --level strong reports each capture as an
unresolved call; the Overcommit Solargraph hook was skipped for that
reason.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
This PR carries only @sg-ignore markers, YARD/RBS annotations and the
config needed to enable strong typecheck. The code changes from
3e8ae51 now live on castwide#1245; restore master code
here:

- rubocop_helpers.rb: back to s.version.version. The local strong
  typecheck reports "Unresolved call to version on String"; marked
  with the 1245 URL. The marker has to sit directly above the call,
  which is inside a backslash-continued string, so the interpolation
  is split across lines to make room for the comment.
- repo.rb, require_paths.rb: back to the o && !o.empty? guard. No
  local typecheck finding, so no marker.
- shell.rb: Shell#profile_test_file inlined back into Shell#profile.
  That puts Shell#profile at AbcSize 110.1/110, so .rubocop_todo.yml
  gains the shell.rb exclusion that the CI regeneration command
  produces.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
Flow-sensitive typing does not narrow a constant, so the nil guard on
File::ALT_SEPARATOR left gsub receiving String, nil and the return
inferring String, Enumerator. Reading it into a local lets the guard
narrow it, which makes both @sg-ignore markers on the method
unneeded. Behaviour is unchanged.

The spec stubs ALT_SEPARATOR so the gsub line runs on platforms
where the constant is nil.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
The rbs signature for the library overload of
RBS::EnvironmentLoader#add requires the version: keyword. nil is the
runtime default, so behaviour is unchanged.

Solargraph still rejects the nil literal against String, nil until
castwide#1223 lands, so the line carries a marker naming
that PR. The marker also covers the pre-existing unresolved gsub on
the untagged library parameter.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
`alias :"" a` parses as s(:alias, s(:dsym), s(:sym, :a)). The
pattern in AliasNode required a first child under each operand, so
it skipped that alias where master created a MethodAlias named "".
Read each operand's name with a separate pattern so every alias
shape maps as before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
Replace positional children reads in NodeMethods (including
DeepInference), Pin::Method#method_body_node, Chain::Literal,
Chain::Parameter, ApiMap#process_macros and
SourceMap#macro_method_candidates with Ruby pattern matching.

The :DEFN / :DEFS checks in method_body_node have no producer and
are left as they were. string_ranges in class_methods.rb is left as
well: each of its reads sits under its own @sg-ignore marker, and
rewriting them would move or drop markers.

drill_signature and splatted_hash? have no callers outside their
own recursion and had no coverage; neither did the SKIPPABLE and
resbody clauses of the compound-statement walk, the block clause
of reduce_to_value_nodes, or method_body_node's fallback. Specs now
cover them; each passes on master too.

Solargraph defines no pins for pattern captures, so typecheck --level
strong reports each capture as an unresolved call; the Overcommit
Solargraph hook was skipped for that reason.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
The constant is created at runtime with const_set, so Solargraph
cannot resolve the bare lexical reference and needed an @sg-ignore.
const_get on the same class returns the same object and typechecks.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
Replace the "Need better overload selection", "track reassignment",
"repeated pure calls" and "Library method has no usable type" labels
with the PR that fixes each site, or a cause-specific label where
none does. Each was re-verified by removing it and typechecking.

- castwide#1338: 9 reassignment sites
- castwide#1258: 5 repeated-pure-call sites
- castwide#1245: host.rb, rbs_map/stdlib.rb, formatting.rb
- castwide#1364, castwide#1231: collection/gem.rb, rubocop_helpers
- castwide/backport#6: the two Backport adapter calls in shell.rb
- JSON.parse is untyped: 4 repo.rb sites
- 12 sites with no known fix are marked unexplained; call.rb:128 is
  a nil false alarm

Restore the two ComplexType.parse @overload tags (partial: false
returns ComplexType, partial: true returns Array<UniqueType>), which
removes its marker. Type Gem::Specification.load in the rubygems fill
as returning Gem::Specification?, which removes the metagem.rb marker.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
This reverts commit e9db25c.

It only typechecks once castwide#1223 lands, and this PR
takes no dependencies on other open PRs. The file returns to its
master content, re-exposing the two pre-existing problems on line 12
(missing path: keyword, unresolved gsub).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
A wildcard workspace accepted any source, so merging one built by
Source.load_string with no filename stored it under a nil key and
filenames returned [nil]. Skip such sources before the include check.
Binding the filename to a local also lets Solargraph see it is a
String, so the Hash#[]= marker goes away.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
ComplexType#first returns nil on an empty type, and calling defined?
on it raised NoMethodError. A nil caller now takes the existing
found.clear path, the same as an undefined one.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
kind is already the Symbol from text&.to_sym, so the second to_sym
only mattered when text was nil, where it raised NoMethodError. Now a
nil kind fails the include? check and returns [] like any other
invalid visibility. The marker for the nil receiver goes with it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
Eleven @sg-ignore markers covered positional children reads that are
now pattern captures; typecheck reports each as Unneeded. The ten
Unneeded markers left in node_methods.rb predate this branch.

SKIP=Solargraph: the hook fails on master for these files already.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
dereference returns nil for an include whose module does not resolve
(include NoSuchMod), and the nil tag went on to ComplexType.parse.
Skip it, as the prepend and extend loops already do.

The spec passes before and after: parsing the nil tag happened to
yield no methods, so it guards the behaviour rather than reproducing
a failure.

The ignore marker stays. It also covers namespace_pin (Pin::Base, nil)
on the same call, the same problem reported unsuppressed on the two
neighbouring inner_get_methods_from_reference calls.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
All three Plugin typecheck jobs (regression on rbs 4.2.0, rails and
rspec on the 4.2.1 prerelease) report a nil-able argument to
JSON.parse at these two lines once the last_line guard moved to 1245.
Local typecheck on macOS does not report them; the cause of that
disagreement is not known yet, so CI is followed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
Each marker was removed and its file typechecked to confirm the
error matches the new label:

- type_checker.rb: gates on a nilable closure -> castwide 1393
- shell.rb: nil literal passed as YARD::Tags::Tag text -> castwide 1223
- source.rb, source/change.rb, source_map.rb -> nil false alarm
- source/updater.rb -> flow sensitive typing needs to track
  reassignment
- api_map/source_to_yard.rb: YARD MethodObject.new namespace doc is
  too narrow -> Library method has no usable type
- rbs_map/stdlib.rb: Missing keyword argument path to
  RBS::EnvironmentLoader#add -> Library method has no usable type;
  castwide 1245 is dropping its version: nil change

Workspace#has_file? now documents filename as [String, nil], which
makes the library.rb maybe_map marker unneeded, so it is removed.

Committed with SKIP=Solargraph only because local typecheck reports
repo.rb:107 and workspace/require_paths.rb:84 as Unneeded; CI needs
both markers. No other typecheck problems.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
code_object_at returns nil when the map holds no MethodObject for the
path, and the docstring=, visibility= and parameters= calls then hit
nil. Skip the pin instead; their three nil-check markers go.

With the outer call no longer failing, the checker reaches the block
and reports Unresolved call to full_name and asgn_code: the pin from
Enumerable<Pin::Method>#each infers as generic<Elem>, so p is
undefined. That is castwide#1318, so the block line now
carries a marker naming it; the count stays at 8.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
ConditionVariable#wait can return without a signal. With an if guard
a spurious wakeup fell through to next_message on an empty queue and
passed nil to Host#receive. Loop until a message is queued.

The receive marker stays: next_message is still declared Hash, nil.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
Eight markers sit on lines castwide 1245 now fixes: the nil caller
in references_from, the redundant to_sym, the unresolved include, the
missing YARD method object, the nil filename in Workspace#merge, and
the MessageWorker wakeup.

SKIP=Solargraph: local typecheck flags the two JSON.parse markers as
unneeded while CI needs them; nothing else is reported.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
The reported error is the reassigned new_signature_pin, which 1338
narrows. Retires the last probably-nil-false-alarm marker.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
This reverts commit 4f2c913.

Restores the version: nil keyword and its castwide 1223 marker in
rbs_map/stdlib.rb. The marker covers the typecheck problem until
castwide#1223 lands, so the call no longer depends on that
PR to typecheck.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
Relabel the "Type as a tuple with union members" markers to the PR
that clears each one: castwide 1223 for the Open3 status destructuring
in repo.rb, library.rb and yardoc.rb and the result[2] reads in
comment_ripper.rb; castwide 1231 for the six to_method.rb markers,
whose @PARAM a tags become Array(String, String | nil). The nilable
@buffer_lines[] read in comment_ripper.rb becomes "nil false alarm".

rubocop-yard rejects the | in those to_method.rb tags (YARD/
TagTypeSyntax: invalid character at |), so to_method.rb joins
comment_ripper.rb in that cop's .rubocop_todo.yml exclusions.

Fix the comment_ripper.rb @type tag: Array([Integer, nil], [Integer,
nil]) parsed as a 4-tuple; it is now Array(Integer, Integer).

call_nodes_from accepts nil and already returns [] for it, so its
@PARAM node now says so. That makes the source_map.rb nil false alarm
marker unneeded (removed) and exposes three node.type calls whose
is_a? guard does not narrow until castwide 1259 lands; each gets a
1259 marker.

rbs_map/stdlib.rb's marker points at castwide 1245 again, which
restores version: nil on that call.

Committed with SKIP=Solargraph: local typecheck reports the markers at
repo.rb:107 and workspace/require_paths.rb:84 as unneeded, but CI
needs both. The full strong typecheck reports only those two.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
Labels only; no code or annotation changes. Each marker was verified
by removing it and typechecking its file.

- send_node.rb, sclass_node.rb #process: castwide#1231,
  whose diff deletes both markers.
- comment_ripper.rb on_embdoc_beg/on_embdoc/on_embdoc_end
  declarations: castwide#1104.
- method.rb to_rbs signatures[1..]: a non-zero-start Range slice,
  so "nil false alarm", not the _NonEmpty narrowing.
- diagnoser.rb tick: queue.shift can return nil after another
  thread drains the queue, so "Need to add nil check here".
- initialize.rb support_workspace_folders? and
  dynamic_registration_for?: params is Hash{String => undefined},
  so the return type is undefined, not a boolish gap.

Committed with SKIP=Solargraph: full typecheck reports two
pre-existing Unneeded @sg-ignore markers, repo.rb:107 and
workspace/require_paths.rb:84, outside this change.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
The three type_checker.rb markers fail because the block parameter pin
does not shadow the outer method parameter of the same name, so
pin.decl resolves against Pin::Method.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
Solargraph checks a **kwargs argument as a single keyword named
kwargs, so any call passing a double splat reports it as an
unrecognized keyword, not only super.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
Solargraph reports super as an unresolved call inside a define_method
block, since the method it overrides is named only at runtime.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
Solargraph adds Boolean to these instance variables inferred types
although none is ever assigned one; 1231 does not change the result.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAm8uhPDwH4Vst3uzZtHU6
apiology and others added 28 commits October 21, 2026 15:43
.rubocop_todo.yml is generated; the integration merge regenerates
it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Undercover flagged the block in Shell#require_plugins that requires
each plugin named by --plugins: the only spec passed an empty string,
so the require, CacheDir.add_plugin and LoadError branches never ran.
Add specs for a loadable plugin and a missing one, and clear the
plugin from CacheDir.plugin_requires after each example.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
A raise or a caller timeout out of the zipped futures value! skipped
pool.shutdown, leaving FixedThreadPool workers mapping gems in the
background. They iterate Convention @@conventions, so a later
Convention.register raised a RuntimeError for adding a key to a hash
during iteration. Kill the pool in an ensure so no worker outlives
the call.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Specs that build a workspace at the repo root load the plugins in its
.solargraph.yml, as the plugin CI jobs configure, and require_plugins
then records them with CacheDir.add_plugin. That switched
CacheDir.gem_dir to a cold plugin-keyed directory for the rest of the
spec process. Save, clear and restore CacheDir.plugins and
plugin_requires around every example, which also makes the per-spec
CacheDir cleanup in shell_spec and config_spec redundant.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Regenerate .rubocop_todo.yml.
A before(:all) workspace load, such as the repo-root ApiMap that
conversions_spec builds, runs outside the per-example around hook, so
the plugins it records stayed in CacheDir for every later example.
Save, clear and restore them around each context as well.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Replace the solargraph gems shell-out in full_spec with in-process
calls to Solargraph::Shell, run once after a plain Workspace.new and
once after Workspace.new(Dir.pwd), the repo-root workspace the specs
load. Each pass caches the same gems the shell command did, so
whichever setup a spec worker runs under finds its pins already built.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Shell.start built its own Repo, so the Workspace.new calls before each
pass changed nothing about where it cached. Cache instead the way the
specs map gems: once with no workspace directory and once through the
repo-root workspace, resolving each gem with a Repo for that
workspace and building the pins with Collection::Gem.load_all.

Drop stdlib from the list. Shell#cache never cached it; the name only
produced a not-found warning.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
ApiMap#catalog does not cache gems: an uncached gem lands in
unloaded_gems with no pins. The conversions, Thor and closure
combination specs therefore passed only on a cache CI had already
warmed, or (Thor) by caching the whole bundle with load_with_cache.

Add a cache_unloaded_gems spec helper that caches the gems a catalog
left unloaded and catalogs again, and use it in all three specs so
each caches just the gems it names, plus their dependencies.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Two External specs (backport via bundler/require and a duplicate
require) and the strict-level kramdown-parser-gfm spec found no pins
on an empty cache, because uncached gems stay in unloaded_gems.

Cache the gems each one leaves unloaded and update or catalog again,
so they pass without a cache CI warmed beforehand.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Resolved spec/type_checker/levels/strict_spec.rb: the kramdown spec
now caches its gem with cache_unloaded_gems, replacing this branch's
before hook that did the same thing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Specs now cache the gems they need, so the warm-up is no longer
required for them to pass on a cold cache.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
The spec stopped the host from a Backport.prepare_interval block. In
Backport 1.2.0, Base#start calls Interval#starting before setting
@started, and the interval thread first checks `until stopped?`. When
that thread runs first it exits without ticking, the block never runs,
and Backport.run sleeps forever (a 300s CI timeout).

Stop the host from a plain thread after the same delay instead.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
(cherry picked from commit 463427d)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
(cherry picked from commit 62804da)
The strong typecheck on 2026-10-19 covers the Rakefile, and it types
filter_map as keeping the nil its block can return, so it flags the
metagems calls. Mark the two lines with the checker gap.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
…Support macros in gem source

api_map.rb: plugin addon catalog, keeping the @processing_macros guard
external.rb: extra gem names methods, keeping the base's YARD tags
send_node.rb: drop class_attribute processing, now in the plugin
type_checker.rb: keep sig.parameters.fetch, allow nil argchain type
spec/collection/gem_spec.rb: keep both sides' examples
spec/external_spec.rb: cache gems in the extra gem names spec
source_map.rb: drop CollectionStyle disable, already off in .rubocop.yml

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
A reader thread blocks inside Convention.for_global while the main
thread registers another convention. Without a fix the register
raises "can't add a new item into set during iteration", the error
the parallel spec workers hit when leaked Library cache threads
catalog while a spec registers a convention.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Convention.register added to the shared @@conventions Set in place
while for_local/for_global/for_object iterated it from other threads,
such as Library background cache threads cataloging an ApiMap, so
the registering thread raised. Register and unregister now build a
new frozen Set under a Mutex and swap it in, so readers iterate an
unchanging snapshot. The public API is unchanged.

(cherry picked from commit be6a875)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
… plugins

Resolves convention.rb by keeping #253's snapshot registry and adding
castwide#1407's CacheDir.add_convention call after it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
…res fail CI again

Regenerate .rubocop_todo.yml.
The Overcommit step in linting.yml has carried continue-on-error with
a @todo to revert in 0.60. Solargraph is now 0.61.0, and the mask
hides real failures on PRs, such as the Solargraph hook crashing with
exit 65 on a YARD::Templates::TemplateOptions alias. Remove it so the
overcommit check reports those failures.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
… again

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Resolve conflicts in 25 files by taking castwide#1418's pattern-matching rewrite
of node.children reads. The integration side's fetch, drop and
nil-guard rewrites from castwide#1245 cover the same reads. Keep the
integration side's deletion of the class_attribute branch in
send_node.rb, its source: :parser closure in ivasgn_node.rb, and its
Boolean @return on Chain::Literal#value.

Remove the markers citing castwide#1418 or made unneeded by it, keep castwide#1416
markers where the error remains, and mark four findings the
combination introduced with "Found after castwide#1418 merged": three in
NodeMethods.call_nodes_from, where is_a? narrowing is lost after a
failed `in` pattern, and the simple_convert(arg.node) call in
Chain::Call.

Regenerate .rubocop_todo.yml under RuboCop 1.92.1; it only drops three
exclusions.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ZFiJrm1ZRz7SAoezTFzYA
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants